/*
 * Timer.cc
 *
 *  Created on: 2021年4月5日
 *      Author: san
 */

#include "Timer.h"
#include <sys/time.h>
#include <unistd.h>
#include <queue>
#include "HttpData.h"

namespace san {

TimerNode::TimerNode(std::shared_ptr<HttpData> requestData, int timeout)
	: deleted_(false),
	  httpDataPtr_(requestData)
{
	struct timeval now;
	gettimeofday(&now, NULL);

	// 以毫秒记（不是马上就删除的， 也不需要那么高的精度）
	expiredTime_ =
	    (((now.tv_sec % 10000) * 1000) + (now.tv_usec / 1000)) + timeout;
}

TimerNode::~TimerNode()
{
	// 到期后执行断开连接操作
	if (httpDataPtr_)
		httpDataPtr_->handleClose();
}

TimerNode::TimerNode(TimerNode &tn)
    : httpDataPtr_(tn.httpDataPtr_), expiredTime_(0)
{
}

void TimerNode::update(int timeout)
{
	// 更新过期时间
	struct timeval now;
	gettimeofday(&now, NULL);
	expiredTime_ =
		(((now.tv_sec % 10000) * 1000) + (now.tv_usec / 1000)) + timeout;
}

bool TimerNode::isValid()
{
	// 若当前时间大于过期时间，则过期，返回 false
	struct timeval now;
	gettimeofday(&now, NULL);
	size_t temp = (((now.tv_sec % 10000) * 1000) + (now.tv_usec / 1000));
	if (temp < expiredTime_)
		return true;
	else
	{
		this->setDeleted();
		return false;
	}
}

void TimerNode::clearReq()
{
	// 断开连接
	httpDataPtr_.reset();
	this->setDeleted();
}

TimerManager::TimerManager() {}

TimerManager::~TimerManager() {}

void TimerManager::addTimer(std::shared_ptr<HttpData> SPHttpData, int timeout)
{
  timerNodePtr_ new_node(new TimerNode(SPHttpData, timeout));
  timerNodeQueue_.push(new_node);

  // ???: 暂时不知道这里是什么意思
  SPHttpData->linkTimer(new_node);
}

void TimerManager::handleExpiredEvent()
{
	// MutexLockGuard locker(lock);
	while (!timerNodeQueue_.empty())
	{
		// pop()之后会调用析构函数， 析构函数里会调用httpdata的 handleClose()
		timerNodePtr_ ptimer_now = timerNodeQueue_.top();
		if (ptimer_now->isDeleted())
			timerNodeQueue_.pop();
		else if (ptimer_now->isValid() == false)
			timerNodeQueue_.pop();
		else
			break;
	}
}

} /* namespace san */
